package com.leyou.search.service.impl;

import com.leyou.common.dto.PageDTO;
import com.leyou.item.client.ItemClients;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpecParamDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.search.entity.Goods;
import com.leyou.search.repository.GoodsRepository;
import com.leyou.search.service.IndexService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class IndexServiceImpl implements IndexService {

    @Autowired
    private ItemClients itemClients;

    @Autowired
    private GoodsRepository repository;


    @Override
    public Goods buildGoods(SpuDTO spuDTO) {
        Goods goods = new Goods();
        BeanUtils.copyProperties(spuDTO, goods);

        //categoryId
        goods.setCategoryId(spuDTO.getCid3());

        ArrayList<String> suggestion = new ArrayList<>();
        String bName = spuDTO.getBrandName();
        suggestion.add(bName);
        //  手机/手机通讯/手机
        String cName = spuDTO.getCategoryName().split("/")[2];
        suggestion.add(cName);

        int length = bName.indexOf("（") == -1 ? bName.length() : bName.indexOf("（");

        String newBName = bName.substring(0, length);
        suggestion.add(cName + newBName);
        suggestion.add(newBName + cName);


        //suggestion
        goods.setSuggestion(suggestion);

        List<SkuDTO> skuDTOS = this.itemClients.listSkuBySpu(spuDTO.getId());

        Long sold = 0L;


        Set<Long> prices = new HashSet<>();

        for (SkuDTO skuDTO : skuDTOS) {
            sold+=skuDTO.getSold();
            prices.add(skuDTO.getPrice());
        }

        //image 从多张图片中以第一个逗号为分隔点截取
        if(!ObjectUtils.isEmpty(skuDTOS)){
            goods.setImage(StringUtils.substringBefore(skuDTOS.get(0).getImages(), ","));
        }

        //prices

        goods.setPrices(prices);

        //sold
        goods.setSold(sold);

        //specs
        //List中包含所有的规格参数以及其对应的值，key，name或者value，一个map对象中有两组实体，分别为eg：name:"CPU品牌",value:"麒麟"
        List<Map<String, Object>> specs = new ArrayList<>();

        List<SpecParamDTO> specParamDTOS = this.itemClients.querySpecParamBySpu(spuDTO.getId(), true);
        if(specParamDTOS == null){
            new ArrayList<Map<String, Object>>();
        }
        specParamDTOS.forEach(specParamDTO -> {

            Map<String, Object> map = new HashMap<>(2);
            map.put("name", specParamDTO.getName());

            //如果某个属性有区间，则需要取出其区间信息，把当前具体的值换成一个区间进行存储
            map.put("value",  choosegment(specParamDTO));
            specs.add(map);

        });

        goods.setSpecs(specs);
        // updatetime
        return goods;

    }

    private Object choosegment(SpecParamDTO p){
        Object value = p.getValue();
        if (value == null || StringUtils.isBlank(value.toString())){
            return "其他";
        }
        if (!p.getNumeric() || StringUtils.isBlank(p.getSegments()) ||value instanceof Collection){
            return value;
        }
        double val = parseDouble(value.toString());
        String result = "其他";

        //保存数值段
        for (String segment : p.getSegments().split(",")) {
            String[] split = segment.split("-");
            //获取数值范围
            double begin = parseDouble(split[0]);
            double end = Double.MAX_VALUE;
            if (split.length == 2){
                end = parseDouble(split[1]);
            }
            //判断是否在范围内
            if (val >= begin && val <end){
                if (split.length ==1){
                    result=split[0] + p.getUnit() + "以上";
                }else if (begin == 0){
                    result =split[1] +p.getUnit() + "以下";
                }else {
                    result=segment+p.getUnit();
                }
                break;
            }
        }
        return result;
    }
    private double parseDouble(String str){
        try {
            return Double.parseDouble(str);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    @Override
    public void loadData() {
        //判断索引库是否存在
        try {
            repository.deleteIndex();
        } catch (Exception e) {

        }

        //创建索引库

        repository.createIndex("{\n" +
                "  \"settings\": {\n" +
                "    \"analysis\": {\n" +
                "      \"analyzer\": {\n" +
                "        \"my_pinyin\": {\n" +
                "          \"tokenizer\": \"ik_smart\",\n" +
                "          \"filter\": [\n" +
                "            \"py\"\n" +
                "          ]\n" +
                "        }\n" +
                "      },\n" +
                "      \"filter\": {\n" +
                "        \"py\": {\n" +
                "\t\t  \"type\": \"pinyin\",\n" +
                "          \"keep_full_pinyin\": true,\n" +
                "          \"keep_joined_full_pinyin\": true,\n" +
                "          \"keep_original\": true,\n" +
                "          \"limit_first_letter_length\": 16,\n" +
                "          \"remove_duplicated_term\": true\n" +
                "        }\n" +
                "      }\n" +
                "    }\n" +
                "  },\n" +
                "  \"mappings\": {\n" +
                "    \"properties\": {\n" +
                "      \"id\": {\n" +
                "        \"type\": \"keyword\"\n" +
                "      },\n" +
                "      \"suggestion\": {\n" +
                "        \"type\": \"completion\",\n" +
                "        \"analyzer\": \"my_pinyin\",\n" +
                "        \"search_analyzer\": \"ik_smart\"\n" +
                "      },\n" +
                "      \"title\":{\n" +
                "        \"type\": \"text\",\n" +
                "        \"analyzer\": \"my_pinyin\",\n" +
                "        \"search_analyzer\": \"ik_smart\"\n" +
                "      },\n" +
                "      \"image\":{\n" +
                "        \"type\": \"keyword\",\n" +
                "        \"index\": false\n" +
                "      },\n" +
                "      \"updateTime\":{\n" +
                "        \"type\": \"date\"\n" +
                "      },\n" +
                "      \"specs\":{\n" +
                "        \"type\": \"nested\",\n" +
                "        \"properties\": {\n" +
                "          \"name\":{\"type\": \"keyword\" },\n" +
                "          \"value\":{\"type\": \"keyword\" }\n" +
                "        }\n" +
                "      }\n" +
                "    }\n" +
                "  }\n" +
                "}");

        int page = 1;

        //分页查询
        while(true){
            PageDTO<SpuDTO> spuDTOPageDTO = this.itemClients.pageQuery(50, page, null, null, null, null);
            //健壮性考虑
            //防止第一页没有数据
            if (spuDTOPageDTO.getTotalPage()==0){
                break;
            }
            List<Goods> goodslist = spuDTOPageDTO
                            .getItems()
                            .stream()
                            .map(spuDTO -> buildGoods(spuDTO))
                            .collect(Collectors.toList());
            repository.saveAll(goodslist);

            page++;
            //不存在下一页停止
            if (page > spuDTOPageDTO.getTotalPage()){
                break;
            }

        }


    }



    @Override
    public void saveGoodsById(Long spuId) {
        //获取当前页的goods对象
        List<SpuDTO> items = this.itemClients.pageQuery(null, null, null, null, null, null).getItems();
        if (!CollectionUtils.isEmpty(items)){
            this.repository.save(buildGoods(items.get(0)));
        }

    }

    @Override
    public void deleteGoodsById(Long spuId) {
        this.repository.deleteById(spuId);
    }
}
